package hannuota;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.*;
//uu
//77
public class AutoMoveDisc extends JDialog implements ActionListener {  //定义了一个名为"AutoMoveDisc"的类，继承自JDialog类，并实现了ActionListener接口
    //声明了一些变量，用于存储盘子数量、柱子对象、柱子名称、界面容器、移动步骤等信息
    int amountOfDisc = 1;
    TowerPoint[] pointA;
    TowerPoint[] pointB;
    TowerPoint[] pointC;
    char[] towerName;
    Container con;
    StringBuffer moveStep;
    JTextArea showStep;
    JButton bStart, bStop, bContinue, bClose;
    Timer time;
    int i = 0, number = 0;

    //用于初始化界面和一些变量，并设置界面的布局、按钮的事件监听器
    AutoMoveDisc(Container con) {
        setModal(true);
        setTitle("搬运过程详情");
        this.con = con;
        moveStep = new StringBuffer();
        time = new Timer(100, this);
        time.setInitialDelay(10);
        showStep = new JTextArea(10, 12);
        bStart = new JButton("演示");
        bStop = new JButton("暂停");
        bContinue = new JButton("继续");
        bClose = new JButton("关闭");
        bStart.addActionListener(this);
        bStop.addActionListener(this);
        bContinue.addActionListener(this);
        bClose.addActionListener(this);
        JPanel south = new JPanel();
        south.setLayout(new FlowLayout());
        south.add(bStart);
        south.add(bStop);
        south.add(bContinue);
        south.add(bClose);
        add(new JScrollPane(showStep), BorderLayout.CENTER);
        add(south, BorderLayout.SOUTH);
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        towerName = new char[3];
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                time.stop();
                setVisible(false);
            }
        });
    }

    // 设置柱子对象、柱子名称和盘子数量等属性
    public void setPointA(TowerPoint[] pointA) {
        this.pointA = pointA;
    }

    public void setPointB(TowerPoint[] pointB) {
        this.pointB = pointB;
    }

    public void setPointC(TowerPoint[] pointC) {
        this.pointC = pointC;
    }

    public void setTowerName(char name[]) {
        if (name[0] == name[1] || name[0] == name[2] || name[1] == name[2]) {
            towerName[0] = 'A';
            towerName[1] = 'B';
            towerName[2] = 'C';
        } else
            towerName = name;
    }

    public void setAmountOfDisc(int n) {
        amountOfDisc = n;
    }
    static long start=0L;
    static long end=0L;
    //这是实现ActionListener接口中的方法，用于处理界面上的按钮点击事件。根据不同的按钮，执行相应的操作
    static  ArrayList<Long> arrayList=new ArrayList<Long>();//用来存储时间信息
    public void actionPerformed(ActionEvent e) {

        if (e.getSource() == time) {
            number++;
            char cStart, cEnd;
            if (i <= moveStep.length() - 2) {
                System.out.println(new Date().getTime());
                arrayList.add(new Date().getTime());
                cStart = moveStep.charAt(i);
                cEnd = moveStep.charAt(i + 1);
                showStep.append("(" + number + ")从" + cStart + "座搬一个盘子到" + cEnd + "座\n");
                autoMoveDisc(cStart, cEnd);
            }
            i = i + 2;
            if (i >= moveStep.length() - 1) {
                JOptionPane.showMessageDialog(null, "耗时"+(arrayList.get(arrayList.size()-1)-arrayList.get(0))+"毫秒", "计算时长", JOptionPane.INFORMATION_MESSAGE);
                arrayList.clear();
                this.time.stop();
            }
        } else if (e.getSource() == bStart) {
            if (moveStep.length() == 0) {
                if (time.isRunning() == false) {
                    i = 0;
                    moveStep = new StringBuffer();
                    setMoveStep(amountOfDisc, towerName[0], towerName[1], towerName[2]);
                    number = 0;
                    this.time.start();
                }
            }
        } else if (e.getSource() == bStop) {
            if (time.isRunning() == true)
                time.stop();
        } else if (e.getSource() == bContinue) {
            if (time.isRunning() == false)
                time.restart();
        } else if (e.getSource() == bClose) {
            time.stop();
            setVisible(false);
        }
    }

    //key，递归实现汉诺塔问题的算法。根据盘子数量和柱子的顺序，将移动步骤记录在moveStep变量中
    private void setMoveStep(int amountOfDisc, char one, char two, char three) {
        if (amountOfDisc == 1) {
            moveStep.append(one);
            moveStep.append(three);
        } else {
            setMoveStep(amountOfDisc - 1, one, three, two);
            moveStep.append(one);
            moveStep.append(three);
            setMoveStep(amountOfDisc - 1, two, one, three);
        }
    }

    //根据传入的起点和终点柱子的名称，获取对应的柱子对象和盘子对象，并进行移动操作
    private void autoMoveDisc(char cStart, char cEnd) {
        Disc disc = null;
        if (cStart == towerName[0]) {
            for (int i = 0; i < pointA.length; i++) {
                if (pointA[i].isHaveDisc() == true) {
                    disc = pointA[i].getDiscOnPoint();
                    pointA[i].setHaveDisc(false);
                    break;
                }
            }
        }
        if (cStart == towerName[1]) {
            for (int i = 0; i < pointB.length; i++) {
                if (pointB[i].isHaveDisc() == true) {
                    disc = pointB[i].getDiscOnPoint();
                    pointB[i].setHaveDisc(false);
                    break;
                }
            }
        }
        if (cStart == towerName[2]) {
            for (int i = 0; i < pointC.length; i++) {
                if (pointC[i].isHaveDisc() == true) {
                    disc = pointC[i].getDiscOnPoint();
                    pointC[i].setHaveDisc(false);
                    break;
                }
            }
        }
        TowerPoint endPoint = null;
        int i = 0;
        if (cEnd == towerName[0]) {
            for (i = 0; i < pointA.length; i++) {
                if (pointA[i].isHaveDisc() == true) {
                    if (i > 0) {
                        endPoint = pointA[i - 1];
                        break;
                    } else if (i == 0)
                        break;
                }
            }
            if (i == pointA.length)
                endPoint = pointA[pointA.length - 1];
        }
        if (cEnd == towerName[1]) {
            for (i = 0; i < pointB.length; i++) {
                if (pointB[i].isHaveDisc() == true) {
                    if (i > 0) {
                        endPoint = pointB[i - 1];
                        break;
                    } else if (i == 0)
                        break;
                }
            }
            if (i == pointB.length)
                endPoint = pointB[pointB.length - 1];
        }
        if (cEnd == towerName[2]) {
            for (i = 0; i < pointC.length; i++) {
                if (pointC[i].isHaveDisc() == true) {
                    if (i > 0) {
                        endPoint = pointC[i - 1];
                        break;
                    } else if (i == 0)
                        break;
                }
            }
            if (i == pointC.length)
                endPoint = pointC[pointC.length - 1];
        }
        if (endPoint != null && disc != null) {
            endPoint.putDisc(disc, con);
            endPoint.setHaveDisc(true);
        }
    }
}